package com.xygz.orm;

import com.xiyuan.smartutils.logging.LogFactory;
import com.xiyuan.smartutils.logging.Logger;
import com.xygz.orm.config.ORMConfig;
import com.xygz.orm.constants.ErrorMessages;
import com.xygz.orm.constants.ORMConstants;
import com.xygz.orm.enums.DbType;
import com.xygz.orm.exception.ORMException;
import com.xygz.orm.transaction.TransactionManager;
import com.xygz.orm.type.TypeResolver;

import javax.sql.DataSource;
import java.sql.SQLException;

/**
 * ORM 管理器
 *
 * @author xiyuan-lgz 2023-10-31 @version v1.0.0 新建与整理
 */
@SuppressWarnings("all")
public abstract class ORMManager implements ErrorMessages, ORMConstants {
    public static final Logger logger = LogFactory.getLogger(ORMManager.class);
    
    /**
     * 获取数据源
     *
     * @param ormId 数据源ID
     * @return 数据源
     * @throws ORMException 异常信息
     */
    public static ORMServer get(String ormId) throws ORMException {
        return instance().getDatabase(ormId);
    }
    
    /**
     * 获取默认的数据源
     *
     * @return 数据源
     * @throws ORMException 异常信息
     */
    public static ORMServer get() throws ORMException {
        return instance().getDatabase();
    }
    
    /**
     * 注册一个数据库服务
     *
     * @param parameter 数据库连接参数
     * @return
     * @throws SQLException SQL 异常
     * @throws ORMException ORM 异常
     */
    public static ORMServer register(ORMParameter parameter) throws SQLException, ORMException {
        return instance().registerDatabase(parameter);
    }
    
    /**
     * 注册一个数据库服务
     *
     * @param parameter  数据库连接参数
     * @param dataSource 数据库连接池
     * @return
     * @throws SQLException SQL 异常
     * @throws ORMException ORM 异常
     */
    public static ORMServer register(ORMParameter parameter, DataSource dataSource) throws SQLException, ORMException {
        return instance().registerDatabase(parameter, dataSource);
    }
    
    static <E, C extends ConditionWrapper<E, C>> C createConditioner(Class<C> c, Class<E> en) {
        try {
            return instance().builder().createConditioner(c, en);
        }
        catch (ORMException e) {throw e;}
        catch (Throwable e) {
            throw new ORMException(e.getMessage(), e);
        }
    }
    
    static <E, C extends ConditionWrapper<E, C>> C createConditioner(Class<C> c, E en) {
        try {
            return instance().builder().createConditioner(c, en);
        }
        catch (RuntimeException e) {throw e;}
        catch (Throwable e) {
            throw new RuntimeException(e);
        }
    }
    
    public static <M extends ORMManager> M instance() throws ORMException {
        return ORMLoader.init();
    }
    
    /**
     * 注册数据库服务
     *
     * @param parameter  连接参数
     * @param dataSource 数据元
     * @return
     * @throws SQLException 数据库异常
     * @throws ORMException ORM异常
     */
    protected abstract ORMServer registerDatabase(ORMParameter parameter, DataSource dataSource) throws SQLException, ORMException;
    
    /**
     * 注册数据库服务
     *
     * @param parameter 连接参数
     * @throws SQLException 数据库异常
     * @throws ORMException ORM异常
     */
    protected abstract ORMServer registerDatabase(ORMParameter parameter) throws SQLException, ORMException;
    
    protected abstract void releaseDatabase(String id);
    
    /**
     * 获取数据库服务
     *
     * @return 数据库服务实例
     * @throws ORMException ORM异常
     */
    protected abstract ORMServer getDatabase() throws ORMException;
    
    /**
     * 获取数据库服务
     *
     * @param id 数据库beanName
     * @return 数据库服务实例
     * @throws ORMException ORM异常
     */
    protected abstract ORMServer getDatabase(String id) throws ORMException;
    
    /***
     * 获取构建器
     * @return 构造器
     */
    public abstract ORMBuilder builder();
    
    
    public abstract SQLBuilder getSQLBuilder(DbType dbType) throws ORMException;
    
    public abstract ORMProvider getProvider(DbType dbType) throws ORMException;
    
    /**
     * 获取 dbo 管理器
     *
     * @return dbo
     */
    public abstract EntityManager getEntityManager();
    
    /**
     * 获取类型转换器
     *
     * @return 类型转换器
     */
    public abstract TypeResolver getTypeResolver();
    
    /**
     * 获取条件构造器
     *
     * @return 条件构造器
     */
    protected abstract ConditionBuilder getConditionBuilder();
    
    /**
     * 设置事务管理器
     *
     * @param transactionManager 事务管理器
     */
    public abstract void setTransactionManager(TransactionManager transactionManager);
    
    /**
     * 获取事务管理器
     *
     * @return 事务管理器
     */
    public abstract TransactionManager getTransactionManager();
    
    /**
     * 获取框架默认事务管理器，不依赖其他事务管理器
     *
     * @return 事务管理器
     */
    public abstract TransactionManager getDefaultTransactionManager();
    
    /**
     * 获取 全局配置
     *
     * @return 获取配置
     */
    public abstract ORMConfig getGlobalConfig();
    
    /**
     * 设置全局 配置
     *
     * @param config 全局设置
     */
    public abstract void setGlobalConfig(ORMConfig config);
    
    
    public abstract void setContextHolder(ORMDataSourceContextHolder contextHolder);
    
    protected abstract void init() throws ORMException;
}
